package com.test.esfiledemo.controller;

import com.alibaba.fastjson.JSONArray;
import com.test.esfiledemo.bean.EsSearchBean;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

@RestController
@RequestMapping("/ss")
public class HelloWorldController {
    @Resource
    private RestHighLevelClient restHighLevelClient;

    @RequestMapping(value = "/addfile")
    public String addfile() {
        String basePath = "/Users/libin/Desktop/1";
        File dir = new File(basePath);
        List<File> allFileList = new ArrayList<>();

        // 判断文件夹是否存在
        if (!dir.exists()) {
            System.out.println("目录不存在");
            return null;
        }

        getAllFile(dir, allFileList);

        for (File file : allFileList) {
            System.out.println(file.getName());
            try {
                String bas64content = pdfToBase64(file);
                Map<String, Object> jsonMap = new HashMap<>();
                jsonMap.put("fileid", UUID.randomUUID().toString().trim().replaceAll("-", ""));
                jsonMap.put("filename", file.getName());
                jsonMap.put("content", bas64content);
                //IndexRequest request= new IndexRequest("fileindex") .setPipeline("attachment").source(jsonMap).id("1508d211717b4dca87864c6930aff943");
                IndexRequest request = new IndexRequest("fileindex").setPipeline("attachment").source(jsonMap);
                IndexResponse index = restHighLevelClient.index(request, RequestOptions.DEFAULT);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        System.out.println("该文件夹下共有" + allFileList.size() + "个文件");

        return null;
    }

    @RequestMapping(value = "/testfile")
    public void testfile() throws Exception {
        String bas64content = pdfToBase64("http://192.168.65.120:8888/group1/M00/00/1C/wKhBeGJmChiAJP-DAAFihpqeSSA156.pdf");
        Map<String, Object> jsonMap = new HashMap<>();
        jsonMap.put("fileid", "1508d211717b4dca87864c6930aff943");
        jsonMap.put("filename", "测试－0422－001.pdf");
        jsonMap.put("filepath", "http://192.168.65.120:8888/group1/M00/00/1C/wKhBeGJmChiAJP-DAAFihpqeSSA156.pdf");
        jsonMap.put("data", bas64content);
        jsonMap.put("departid", "99990002000300011536");
        IndexRequest request = new IndexRequest("fileindex").setPipeline("attachment").source(jsonMap);
        IndexResponse index = restHighLevelClient.index(request, RequestOptions.DEFAULT);//执行
        System.out.println(index);
    }

    @RequestMapping(value = "/search")
    public String search(EsSearchBean esSearchBean, Integer pageNum, Integer pageSize) throws Exception {
        JSONArray jsonArray = new JSONArray();
        if ((StringUtils.isBlank(esSearchBean.getFileName()) && StringUtils.isBlank(esSearchBean.getFileData())) || StringUtils.isBlank(esSearchBean.getDepartId())) {
            return jsonArray.toString();
        }

        //默认根据文件内容查询
        String search_field = "attachment.content";
        String search_filed_value = esSearchBean.getFileData();

        // 创建搜索请求对象
        SearchRequest request = new SearchRequest();
        request.indices("fileindex");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        // 查询所有数据
        //sourceBuilder.query(QueryBuilders.matchAllQuery());
        //request.source(sourceBuilder);

        //分页参数
        sourceBuilder.from(pageNum).size(pageSize);

        // 构建查询的请求体
        if (StringUtils.isNotBlank(esSearchBean.getFileData())) {
            search_field = "attachment.content";
        } else {
            search_field = "filename";
            search_filed_value = esSearchBean.getFileName();
        }

        BoolQueryBuilder queryBuilders = new BoolQueryBuilder();
        queryBuilders.must(QueryBuilders.termQuery(search_field, search_filed_value));
        queryBuilders.must(QueryBuilders.termQuery("departid", esSearchBean.getDepartId()));
        sourceBuilder.query(queryBuilders);

        //request.source(sourceBuilder);


        //查询字段过滤
        String[] excludes = {"attachment", "departid"};
        String[] includes = {};
        sourceBuilder.fetchSource(includes, excludes);

        //构建高亮字段
        HighlightBuilder highlightBuilder = new HighlightBuilder()
                .preTags("<font color='red'>")
                .postTags("</font>")
                .fragmentSize(200)
                .field(search_field);
        //设置高亮构建对象
        sourceBuilder.highlighter(highlightBuilder);
        //设置请求体
        request.source(sourceBuilder);


        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        if (response.status() != RestStatus.OK) {
            return jsonArray.toString();
        }


        SearchHits hits = response.getHits();
        System.out.println(hits.getTotalHits());
        System.out.println(hits.getMaxScore());
        //for (SearchHit hit : hits) {
        //    //System.out.println(hit.getSourceAsString());
        //    jsonArray.add(hit.getSourceAsString());
        //}
        //return jsonArray.toString();


        //获取查询结果
        for (SearchHit hit : hits) {
            Map<String, Object> map = hit.getSourceAsMap();
            //获取高亮字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField titleField = highlightFields.get(search_field);
            //千万记得要记得判断是不是为空,不然你匹配的第一个结果没有高亮内容,那么就会报空指针异常,这个错误一开始真的搞了很久
            if (titleField != null) {
                Text[] fragments = titleField.fragments();
                map.put("highlight", fragments[0].string());
            }
            jsonArray.add(map);
        }

        return jsonArray.toString();


        //try {
        //    SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //    SearchHits hits = response.getHits();
        //    for (SearchHit hit : hits) {
        //        //输出每条查询的结果信息
        //        System.out.println(hit.getSourceAsString());
        //    }
        //} catch (Exception e) {
        //    e.printStackTrace();
        //}
        //return null;
        // 查询匹配
        //SearchHits hits = response.getHits();
        //System.out.println("took:" + response.getTook());
        //System.out.println("timeout:" + response.isTimedOut());
        //System.out.println("total:" + hits.getTotalHits());
        //System.out.println("MaxScore:" + hits.getMaxScore());
        //System.out.println("hits========>>");

        //System.out.println("<<========");
    }


    public static String pdfToBase64(String contentpath) throws IOException {
        InputStream is = null;
        URL url2 = new URL(contentpath);
        HttpURLConnection conn = (HttpURLConnection) url2.openConnection();
        conn.setDoInput(true);
        conn.connect();
        is = conn.getInputStream();
        //将图片文件转化为字节数组字符串，并对其进行Base64编码处理
        byte[] data = null;
        // 读取图片字节数组
        try {
            ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
            byte[] buff = new byte[1000];
            int rc = 0;
            while ((rc = is.read(buff, 0, 1000)) > 0) {
                swapStream.write(buff, 0, rc);
            }
            data = swapStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return new BASE64Encoder().encode(data).replace("\n", "").replace("\r", "");
    }

    public static String pdfToBase64(File file) throws IOException {
        InputStream is = new FileInputStream(file);
        //将图片文件转化为字节数组字符串，并对其进行Base64编码处理
        byte[] data = null;
        // 读取图片字节数组
        try {
            ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
            byte[] buff = new byte[1000];
            int rc = 0;
            while ((rc = is.read(buff, 0, 1000)) > 0) {
                swapStream.write(buff, 0, rc);
            }
            data = swapStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            is.close();
        }
        return new BASE64Encoder().encode(data).replace("\n", "").replace("\r", "");
    }



    public static void getAllFile(File fileInput, List<File> allFileList) {
        // 获取文件列表
        File[] fileList = fileInput.listFiles();
        if(fileList!=null){
            for (File file : fileList) {
                if (file.isDirectory()) {
                    // 递归处理文件夹
                    // 如果不想统计子文件夹则可以将下一行注释掉
                    getAllFile(file, allFileList);
                } else {
                    // 如果是文件则将其加入到文件数组中
                    allFileList.add(file);
                }
            }
        }

    }

}